
package com.hlkj.pay.service.pay.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.List;

import com.hlkj.pay.enums.PayEnums;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.pay.common.constants.RedisConstants;
import com.hlkj.pay.dto.pay.PayChannelDictQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.infrastructure.mapper.pay.PayChannelDictMapper;
import com.hlkj.pay.infrastructure.mapper.pay.PayChannelDictMappingMapper;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDictDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDictMappingDO;
import com.hlkj.pay.service.pay.IPayChannelDictService;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;

/**
 * @author HlpayTeam
 * @date 2024/09/25 11:12
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PayChannelDictServiceImpl implements IPayChannelDictService {

    private final PayChannelDictMapper payChannelDictMapper;

    private final PayChannelDictMappingMapper payChannelDictMappingMapper;

    @Override
    public List<PayChannelDictDO> queryList(PayChannelDictQueryDto channelDictQueryDO) {
        if (StringUtils.hasText(channelDictQueryDO.getChannelCode()) && StringUtils.hasText(channelDictQueryDO.getDictKey())) {
            PayChannelDictMappingDO payChannelDictMappingDO = payChannelDictMappingDO(channelDictQueryDO.getChannelCode(), channelDictQueryDO.getDictKey());
            if (payChannelDictMappingDO != null) {
                channelDictQueryDO.setChannelCode(payChannelDictMappingDO.getTargetChannelCode());
                if (StringUtils.hasText(payChannelDictMappingDO.getTargetDictKey())) {
                    channelDictQueryDO.setDictKey(payChannelDictMappingDO.getTargetDictKey());
                }
            }
        }
        return payChannelDictMapper.selectList(buildWrapper(channelDictQueryDO));
    }

    @Override
    public PayChannelDictDO queryChannelDict(String channelCode, String dictKey, String dictValue) {
        PayChannelDictQueryDto channelDictQueryDO = new PayChannelDictQueryDto();
        channelDictQueryDO.setChannelCode(channelCode);
        channelDictQueryDO.setDictKey(dictKey);
        channelDictQueryDO.setDictValue(dictValue);
        if (StringUtils.hasText(channelDictQueryDO.getChannelCode()) && StringUtils.hasText(channelDictQueryDO.getDictKey())) {
            PayChannelDictMappingDO payChannelDictMappingDO = payChannelDictMappingDO(channelDictQueryDO.getChannelCode(), channelDictQueryDO.getDictKey());
            if (payChannelDictMappingDO != null) {
                channelDictQueryDO.setChannelCode(payChannelDictMappingDO.getTargetChannelCode());
                if (StringUtils.hasText(payChannelDictMappingDO.getTargetDictKey())) {
                    channelDictQueryDO.setDictKey(payChannelDictMappingDO.getTargetDictKey());
                }
            }
        }
        LambdaQueryWrapper<PayChannelDictDO> queryWrapper = buildWrapper(channelDictQueryDO);
        queryWrapper.last("limit 1");
        return payChannelDictMapper.selectOne(queryWrapper);
    }

    @Cacheable(value = RedisConstants.PAY_CHANNEL_DICT_MAPPING, key = "#channelCode+'_'+#dictKey", unless = "#result == null")
    public PayChannelDictMappingDO payChannelDictMappingDO(String channelCode, String dictKey) {
        // 先按照 通道编号和字典key 进行匹配
        PayChannelDictMappingDO payChannelDictMappingDO = new PayChannelDictMappingDO();
        payChannelDictMappingDO.setChannelCode(channelCode);
        payChannelDictMappingDO.setDictKey(dictKey);
        payChannelDictMappingDO.setType(CommonEnum.YES_NO_TYPE.NO.getCode());
        LambdaQueryWrapper<PayChannelDictMappingDO> queryWrapper = buildWrapper(payChannelDictMappingDO);
        queryWrapper.last("limit 1");
        List<PayChannelDictMappingDO> payChannelDictMappingList = payChannelDictMappingMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(payChannelDictMappingList)) {
            payChannelDictMappingDO.setDictKey(null);
            payChannelDictMappingDO.setType(CommonEnum.YES_NO_TYPE.YES.getCode());
            queryWrapper = buildWrapper(payChannelDictMappingDO);
            payChannelDictMappingList = payChannelDictMappingMapper.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(payChannelDictMappingList)) {
                return null;
            }
            else {
                PayChannelDictMappingDO commonMapping = payChannelDictMappingList.get(0);
                payChannelDictMappingDO.setChannelCode(commonMapping.getTargetChannelCode());
                payChannelDictMappingDO.setDictKey(dictKey);
                queryWrapper = buildWrapper(payChannelDictMappingDO);
                payChannelDictMappingList = payChannelDictMappingMapper.selectList(queryWrapper);
                if (CollectionUtils.isEmpty(payChannelDictMappingList)) {
                    return commonMapping;
                }
                else {
                    return payChannelDictMappingList.get(0);
                }
            }
        }
        else {
            return payChannelDictMappingList.get(0);
        }
    }

    @Override
    public void addList(List<PayChannelDictDO> payChannelDictList) {
        payChannelDictMapper.insertBatch(payChannelDictList);
    }

    /**
     * 查询条件封装
     *
     * @param payChannelDictQueryDto
     * @return
     */
    LambdaQueryWrapper<PayChannelDictDO> buildWrapper(PayChannelDictQueryDto payChannelDictQueryDto) {
        LambdaQueryWrapperX<PayChannelDictDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(PayChannelDictDO::getChannelCode, payChannelDictQueryDto.getChannelCode());
        queryWrapper.eqIfPresent(PayChannelDictDO::getDictKey, payChannelDictQueryDto.getDictKey());
        queryWrapper.eqIfPresent(PayChannelDictDO::getParentDictKey, payChannelDictQueryDto.getParentDictKey());
        queryWrapper.eqIfPresent(PayChannelDictDO::getDictLevel, payChannelDictQueryDto.getDictLevel());
        queryWrapper.eqIfPresent(PayChannelDictDO::getDictValue, payChannelDictQueryDto.getDictValue());
        queryWrapper.orderByAsc(PayChannelDictDO::getSort);
        return queryWrapper;
    }

    /**
     * 查询条件封装
     *
     * @param payChannelDictMappingDO
     * @return
     */
    LambdaQueryWrapper<PayChannelDictMappingDO> buildWrapper(PayChannelDictMappingDO payChannelDictMappingDO) {
        LambdaQueryWrapperX<PayChannelDictMappingDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(PayChannelDictMappingDO::getChannelCode, payChannelDictMappingDO.getChannelCode());
        queryWrapper.eqIfPresent(PayChannelDictMappingDO::getDictKey, payChannelDictMappingDO.getDictKey());
        queryWrapper.eqIfPresent(PayChannelDictMappingDO::getType, payChannelDictMappingDO.getType());
        return queryWrapper;
    }
}
